package com.primestone.cim.dashboardforcim.repo;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.primestone.cim.dashboardforcim.domain.ResMeterReadings;

/**
 * @author cesar.mateus
 * May 27, 2013 4:14:14 PM
 * ResMeterReadingsDaoImpl.java
 * dashboardForCIM
 * 
 */
@Repository
@Transactional
public class ResMeterReadingsDaoImpl implements ResMeterReadingsDao
{
    @Autowired
    private EntityManager em;

    @Override
	public ResMeterReadings findById(Long id)
    {
        return this.em.find(ResMeterReadings.class, id);
    }
    
    @Override
	public List<ResMeterReadings> findAllOrderedByJsonResultDate(Date jsonResultDate)
    {
        CriteriaBuilder builder = this.em.getCriteriaBuilder();
        CriteriaQuery<ResMeterReadings> criteria = builder.createQuery(ResMeterReadings.class);
        Root<ResMeterReadings> resMeterReadings = criteria.from(ResMeterReadings.class);

        /*
         * Swap criteria statements if you would like to try out type-safe criteria queries, a new
         * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
         */

        criteria.select(resMeterReadings)
        .where(builder.equal(resMeterReadings.get("jsonResultDate"), jsonResultDate))
        .orderBy(builder.asc(resMeterReadings.get("jsonResultDate")));
        return this.em.createQuery(criteria).getResultList();
    }
    
    @Override
	public List<ResMeterReadings> findAllOrderedByJsonResultDate()
    {
        CriteriaBuilder builder = this.em.getCriteriaBuilder();
        CriteriaQuery<ResMeterReadings> criteria = builder.createQuery(ResMeterReadings.class);
        Root<ResMeterReadings> resMeterReadings = criteria.from(ResMeterReadings.class);

        /*
         * Swap criteria statements if you would like to try out type-safe criteria queries, a new
         * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
         */

        criteria.select(resMeterReadings)
        .orderBy(builder.asc(resMeterReadings.get("jsonResultDate")));
        return this.em.createQuery(criteria).getResultList();
    }
    
    @Override
	public List<ResMeterReadings> findAllOrderedByUsername(String username)
    {
        CriteriaBuilder builder = this.em.getCriteriaBuilder();
        CriteriaQuery<ResMeterReadings> criteria = builder.createQuery(ResMeterReadings.class);
        Root<ResMeterReadings> resMeterReadings = criteria.from(ResMeterReadings.class);

        /*
         * Swap criteria statements if you would like to try out type-safe criteria queries, a new
         * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
         */

        criteria.select(resMeterReadings)
        .where(builder.equal(resMeterReadings.get("username"), username))
        .orderBy(builder.asc(resMeterReadings.get("username")));
        return this.em.createQuery(criteria).getResultList();
    }

    @Override
	public List<ResMeterReadings> findAllOrderedByUsername()
    {
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<ResMeterReadings> criteria = cb.createQuery(ResMeterReadings.class);
        Root<ResMeterReadings> resMeterReadings = criteria.from(ResMeterReadings.class);

        /*
         * Swap criteria statements if you would like to try out type-safe criteria queries, a new
         * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
         */

        criteria.select(resMeterReadings)
        .orderBy(cb.asc(resMeterReadings.get("username")));
        return this.em.createQuery(criteria).getResultList();
    }
    
    @Override
	public List<ResMeterReadings> findAllOrderedByTicket(String ticket)
    {
        CriteriaBuilder builder = this.em.getCriteriaBuilder();
        CriteriaQuery<ResMeterReadings> criteria = builder.createQuery(ResMeterReadings.class);
        Root<ResMeterReadings> resMeterReadings = criteria.from(ResMeterReadings.class);

        /*
         * Swap criteria statements if you would like to try out type-safe criteria queries, a new
         * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
         */

        criteria.select(resMeterReadings)
        .where(builder.equal(resMeterReadings.get("ticket"), ticket))
        .orderBy(builder.asc(resMeterReadings.get("ticket")));
        return this.em.createQuery(criteria).getResultList();
    }
    
    @Override
	public List<ResMeterReadings> findAllOrderedByTicket()
    {
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<ResMeterReadings> criteria = cb.createQuery(ResMeterReadings.class);
        Root<ResMeterReadings> resMeterReadings = criteria.from(ResMeterReadings.class);

        /*
         * Swap criteria statements if you would like to try out type-safe criteria queries, a new
         * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
         */

        criteria.select(resMeterReadings)
        .orderBy(cb.asc(resMeterReadings.get("ticket")));
        return this.em.createQuery(criteria).getResultList();
    }
    
    /**
     * SELECT c.currency, SUM(c.population)
FROM Country c
WHERE 'Europe' MEMBER OF c.continents
GROUP BY c.currency
HAVING COUNT(c) > 1
can be built using the criteria query API as follows:

  CriteriaQuery<Country> q = cb.createQuery(Country.class);
  Root<Country> c = q.from(Country.class);
  q.select(c.get("currency"), cb.sum(c.get("population")));
  q.where(cb.isMember("Europe", c.get("continents")));
  q.groupBy(c.get("currency"));
  g.having(cb.gt(cb.count(c), 1));
  
  select o.username, count(o.id) from ResMeterReadings o group by o.username
     * @return
     */
    public List getCounts() {
    	CriteriaBuilder cb = this.em.getCriteriaBuilder();
    	CriteriaQuery<ResMeterReadings> q = cb.createQuery(ResMeterReadings.class);
//    	  Root<ResMeterReadings> r = q.from(ResMeterReadings.class);
//    	  q.select(r.get("username"), cb.count(r.get("id")));
//    	  //q.where(cb.isMember("Europe", r.get("continents")));
//    	  q.groupBy(r.get("username"));
//    	  //g.having(cb.gt(cb.count(r), 1));
    	//TODO
    	return null;
    }
    

//    public void register(Member member)
//    {
//        em.persist(member);
//        return;
//    }
}
